<?php

/**
 * This is the model class for table "product".
 *
 * The followings are the available columns in table 'product':
 * @property integer $id
 * @property integer $category_id
 * @property integer $producer_id
 * @property string $code
 * @property integer $state
 * @property integer $price
 * @property double $promotion
 * @property string $status
 * @property integer $featured
 * @property string $created_at
 * @property string $updated_at
 */
class Product extends CActiveRecord {

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Product the static model class
     */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return 'product';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('category_id, producer_id', 'required'),
            array('status', 'default', 'value' => 'yes'),
            array('category_id, producer_id, state, featured', 'numerical', 'integerOnly' => true),
            array('price, promotion', 'numerical'),
            array('code, status', 'length', 'max' => 10),
            array('created_at, updated_at', 'safe'),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, category_id, producer_id, code, state, price, promotion, status, featured, created_at, updated_at', 'safe', 'on' => 'search'),
        );
    }

    /**
     * set timestamp before save
     */
    public function beforeSave() {
        if ($this->isNewRecord)
            $this->created_at = new CDbExpression('NOW()');
        $this->updated_at = new CDbExpression('NOW()');
        return parent::beforeSave();
    }

    /**
     * delete all product details and product images before
     */
    public function beforeDelete() {
        ProductDetail::model()->deleteAllByProductID($this->id);
        ProductImage::model()->deleteAllByProduct($this);
        return parent::beforeDelete();
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'category' => array(self::BELONGS_TO, 'Category', 'category_id'),
            'producer' => array(self::BELONGS_TO, 'Producer', 'producer_id'),
            'productImages' => array(self::HAS_MANY, 'ProductImage', 'product_id'),
            'productDetails' => array(self::HAS_MANY, 'ProductDetail', 'product_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'id' => Yii::t('product', 'id'),
            'category_id' => Yii::t('product', 'categoryId'),
            'producer_id' => Yii::t('product', 'producerId'),
            'code' => Yii::t('product', 'code'),
            'state' => Yii::t('product', 'state'),
            'price' => Yii::t('product', 'price'),
            'promotion' => 'Promotion',
            'status' => Yii::t('product', 'status'),
            'featured' => Yii::t('product', 'featured'),
            'created_at' => Yii::t('product', 'createdAt'),
            'updated_at' => Yii::t('product', 'updatedAt'),
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('category_id', $this->category_id);
        $criteria->compare('producer_id', $this->producer_id);
        $criteria->compare('code', $this->code, true);
        $criteria->compare('state', $this->state);
        $criteria->compare('price', $this->price);
        $criteria->compare('promotion', $this->promotion);
        $criteria->compare('status', $this->status, true);
        $criteria->compare('featured', $this->featured);
        $criteria->compare('created_at', $this->created_at, true);
        $criteria->compare('updated_at', $this->updated_at, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'pagination' => array(
                'pageSize' => Constant::PAGE_SIZE,
            ),
        ));
    }

    public function getCategory() {
        //return Category::model()->findByPk($this->category_id);
        return $this->category;
    }

    /**
     * get category name
     */
    public function getCategoryName() {
        return Category::model()->getCategoryNameById($this->category_id);
    }

    /**
     * get producer name
     */
    public function getProducerName() {
        return Producer::model()->findByPk($this->producer_id)->name;
    }

    /**
     * get state name
     */
    public function getStateName() {
        $stateName = Yii::t('product', 'In stock');
        if ($this->state == 1) {
            $stateName = Yii::t('product', 'In stock');
        } else {
            $stateName = Yii::t('product', 'Out of stock');
        }
        return $stateName;
    }

    /**
     * get product detail and cast corresponding 
     */
    public function getProductDetail($language = 'en') {
        $result = null;
        $productDetails = $this->productDetails;
        foreach ($productDetails as $productDetail) {
            if ($productDetail->language == $language) {
                $result = $productDetail;
            }
        }
        return $result;
    }

    public function productDetail() {
        $language = Yii::app()->language;
        if (!isset($language)) {
            $language = 'en';
        }
        return $this->getProductDetail($language);
    }

    public function getUrl() {
        return Yii::app()->createUrl('product/view', array(
                    'id' => $this->id,
                    'productkey' => $this->productDetail()->seokey,
                    'categorykey' => $this->category->categoryDetail()->seokey,
        ));
    }

    public function createCriteria($criteriaType, $parameters = array()) {
        $criteria = new CDbCriteria;
        $criteria->alias = 'p';
        $criteria->distinct = true;
        $criteria->join = 'left join product_detail pd on p.id = pd.product_id';
        $criteria->join .= ' left join product_image pi on p.id = pi.product_id';

        switch ($criteriaType) {
            case 'by_category_list':
                $category = new Category;
                $category = Category::model()->findByPk($parameters['cat_id']);
                $criteria->compare('pd.language', Yii::app()->language, false);
                $criteria->compare('p.status', 'yes', false);

                $criteria2 = new CDbCriteria;
                if (count($category->childs) == 0) {
                    $criteria2->compare('p.category_id', $parameters['cat_id'], false);
                } else {
                    $categories = $category->childs;
                    foreach ($categories as $cat) {
                        $criteria2->compare('p.category_id', $cat->id, false, 'OR');
                    }
                }
                $criteria->mergeWith($criteria2, true);
                break;

            case 'by_category':
                $criteria->addCondition(array('p.category_id = :category_id',
                    'pd.language = :language',
                    'pi.featured = :featured',
                    'p.status = :status'));
                $criteria->params = array(':category_id' => $parameters['cat_id'],
                    ':language' => Yii::app()->language,
                    ':featured' => 1,
                    ':status' => 'yes');
                break;

            case 'featured_product':
                $criteria->addCondition(array('p.category_id is not null',
                    'p.featured = :pfeatured',
                    'pd.language = :language',
                    'p.status = :status'));
                $criteria->params = array(':pfeatured' => 1,
                    ':language' => Yii::app()->language,
                    ':status' => 'yes');
                $criteria->order = 'pd.name asc';
                $criteria->limit = Constant::FIRST_PAGE_SIZE;
                break;
            case 'newest':
                $criteria->addCondition(array('pd.language = :language',
                    'p.status = :status'));
                $criteria->params = array(':language' => Yii::app()->language,
                    ':status' => 'yes');
                $criteria->order = 'p.created_at asc';
                $criteria->limit = Constant::FIRST_PAGE_SIZE;
                break;
            default:
                $criteria->addCondition(array('pd.language = :language',
                    'p.status = :status'));
                $criteria->params = array(':language' => Yii::app()->language,
                    ':status' => 'yes');
                break;
        }
        return $criteria;
    }

    public function findProducts($criteria, $excerptNumber = NULL) {
        $products = array();

        $results = Product::model()->findAll($criteria);
        if (count($results) == 0) {
            return array();
        }

        foreach ($results as $p) {
            $product = array();
            $product['id'] = $p->id;
            $product['price'] = $p->price;
            $product['url'] = $p->getUrl();
            $product['name'] = '';
            $product['content'] = '';
            $product['image'] = '';
            $product['promotion'] = $p->promotion;

            if (count($p->productDetails) > 0) {
                if ($excerptNumber != NULL) {
                    $arrayStr = Util::getExcerpt($p->productDetails[0]->name, $excerptNumber);
                    $product['name'] = $arrayStr['excerpt'] . '...';
                } else {
                    $product['name'] = $p->productDetails[0]->name;
                }
                $product['seokey'] = $p->productDetails[0]->seokey;
                $product['content'] = $p->productDetails[0]->content;
            }
            if (count($p->productImages) > 0) {
                $product['image'] = Yii::app()->getBaseUrl(true) . '/' . $p->productImages[0]->path;
            }
            $products[] = $product;
        }
        return $products;
    }

    public function getFirstpageListProducts($criteria, $limitItem = Constant::FIRST_PAGE_SIZE, $pageSize = Constant::PAGE_SIZE, $excerptNumber = NULL) {
        if ($criteria == null) {
            return;
        }
        // count result to display multipages, count seem not apply limit
        $productCount = Product::model()->count($criteria);
        $itemCount = min($productCount,$limitItem);
        $pages = new CMyPagination($itemCount);

        // results per page
        if ($pageSize != -1) {
            $pages->pageSize = $pageSize;
        } else {
            // no pagging (list all in one page)
            $pages->pageSize = $itemCount;
        }
        if ($pages->pageSize > $limitItem)
            $pages->pageSize = $limitItem;

        $pages->applyLimit($criteria);
        $products = $this->findProducts($criteria, $excerptNumber);

        return array('products' => $products, 'pages' => $pages);
    }

    public function listProducts($criteria, $pageSize = Constant::PAGE_SIZE, $excerptNumber = NULL) {
        if ($criteria == null) {
            return;
        }
        // count result to display multipages
        $count = Product::model()->count($criteria);
        $pages = new CMyPagination($count);

        // results per page
        if ($pageSize != -1) {
            $pages->pageSize = $pageSize;
        } else {
            // no pagging (list all in one page)
            $pages->pageSize = $count;
        }

        $pages->applyLimit($criteria);
        $products = $this->findProducts($criteria, $excerptNumber);

        return array('products' => $products, 'pages' => $pages);
    }

}